package main

import (
	"fmt"
	"time"
)

// Author : CSR丶WARRIOR
// Time ： 2020/10/17  19:08
// TOOLS : GoLand
// FILENAME : weibo.go
// STATEMENT: 微博案例
type base struct {
	id   int
	name string
}

//博主类
type bloger struct {
	base
	weiboList []*weibo //博主名下微博列表
	comment   map[int][]*weibo
	fansList  []fansInterface //存储粉丝数据
}

//blog构造器
func newBloger(name string) *bloger {
	b := &bloger{}
	b.name = name
	b.weiboList = make([]*weibo, 0)
	b.comment = make(map[int][]*weibo)
	return b
}

//发布微博
func (b *bloger) releaseBlog(content string, weiboType string) {
	//	创建微博对象
	wb := weibo{
		id:          b.getId(),
		weiboType:   weiboType,
		releaseTime: time.Now(), //当前系统时间
		content:     content,
		releaseMan:  b.name,
		to:          "all fans",
	}
	b.weiboList = append(b.weiboList, &wb)
	//微博发布成功后，向粉丝发送通知
	b.notifyFans(wb.id)
}
func (b *bloger) getId() int {
	//获取切片中最后一条微博的id
	var newId int
	if len(b.weiboList) == 0 {
		newId = 1
	} else {
		newId = b.weiboList[len(b.weiboList)-1].id + 1
	}
	return newId
}

func (b *bloger) getCommentId() int {
	var newId int
	if len(b.comment) == 0 {
		newId = 1
	} else {
		newId = len(b.comment) + 1
	}
	return newId
}

// 博主类的方法实现
//粉丝给博主添加关注
func (b *bloger) attachBloger(f fansInterface) {
	b.fansList = append(b.fansList, f)
}

//粉丝取消关注
func (b *bloger) detachBloger(f fansInterface) {
	var index int
	for i := 0; i < len(b.fansList); i++ {
		if b.fansList[i] == f {
			index = i
			b.fansList = append(b.fansList[:index], b.fansList[index+1:]...)
			break
		}
	}
}

//微博更新后，给粉丝发布通知
func (b *bloger) notifyFans(weiboId int) {
	//从博主的粉丝列表中拿到每一个粉丝的数据，并发送通知
	for _, v := range b.fansList {
		v.acceptNotify(weiboId, b)
	}
}

//粉丝类
type fans struct {
	base
}

//铁粉类
type friendlyFans struct {
	fans
}

//黑粉类
type unfriendlyFans struct {
	fans
}

//使铁粉和黑粉都实现粉丝接口中的抽象方法

//粉丝接受到博主的通知
func (f *friendlyFans) acceptNotify(weiboId int, bi blogInterface) {
	fmt.Printf("Hello:%s你所关注的博主发布了一个新的微博\n", f.name)
	f.commentBlog(weiboId, bi)
}

//粉丝评论博主的微博
func (f *friendlyFans) commentBlog(weiboId int, bi blogInterface) {
	//获取博主发布的新微博
	blogger, ok := bi.(*bloger)
	if ok {
		wb := blogger.findWeiboById(weiboId)
		//fmt.Println(weibo)
		wType := wb.weiboType
		var commentMsg string
		switch wType {
		case "心情":
			commentMsg = "开心一点吗~"
		case "新闻":
			commentMsg = "今天发生啥大事了"
		case "美食":
			commentMsg = "今天三顿都吃啥好?"
		}
		var commentContent = weibo{
			id:          blogger.getCommentId(),
			weiboType:   wType,
			releaseTime: time.Now(),
			content:     commentMsg,
			releaseMan:  f.name,
			to:          blogger.name,
		}
		blogger.comment[weiboId] = append(blogger.comment[weiboId], &commentContent)
	}
}

//获取博主发布的新微博
func (b *bloger) findWeiboById(weiboId int) *weibo {
	for _, v := range b.weiboList {
		if v.id == weiboId {
			return v
		}
	}
	return nil
}

//博主查看粉丝的评论
func (b *bloger) browseComment(wbId int) {
	//展示微博内容
	weibo := b.findWeiboById(wbId)
	fmt.Printf("博主名称：%s\t\t微博内容：%s\n", b.name, weibo.content)
	weiboComment := b.comment[wbId]
	for _, comment := range weiboComment {
		fmt.Print("粉丝名称：", comment.releaseMan)
		fmt.Println("\t\t评论：", comment.content)
	}

}

//粉丝接受到博主的通知
func (u *unfriendlyFans) acceptNotify(weiboId int, bi blogInterface) {
	fmt.Printf("Hello:%s你所关注的博主发布了一个新的微博\n", u.name)
	u.commentBlog(weiboId, bi)
}

//粉丝评论博主的微博
func (u *unfriendlyFans) commentBlog(weiboId int, bi blogInterface) {
	//获取博主发布的新微博
	blogger, ok := bi.(*bloger)
	if ok {
		wb := blogger.findWeiboById(weiboId)
		wType := wb.weiboType
		var commentMsg string //评论的内容
		switch wType {
		case "心情":
			commentMsg = "祝你开心"
		case "新闻":
			commentMsg = "发生什么大事了吗？"
		case "美食":
			commentMsg = "今天三顿都吃啥好？"
		}
		//fmt.Println(weibo)
		//创建weibo对象，并把新的评论存储到博主的评论区中去
		comment := weibo{
			id:          blogger.getCommentId(),
			weiboType:   wType,
			releaseTime: time.Now(),
			content:     commentMsg,
			releaseMan:  u.name,
			to:          blogger.name,
		}
		blogger.comment[weiboId] = append(blogger.comment[weiboId], &comment)
	}
}

//微博类
type weibo struct {
	id        int
	weiboType string
	//微博发布时间
	releaseTime time.Time
	//微博内容
	content string
	// 发布人
	releaseMan string
	//给谁发布的
	to string
}

//博主接口
type blogInterface interface {
	attachBloger(f fansInterface)
	detachBloger(f fansInterface)
	notifyFans(weiboId int)
}

//粉丝接口
type fansInterface interface {
	acceptNotify(weiboId int, bi blogInterface)
	commentBlog(weiboId int, bi blogInterface)
}

func main() {
	bloger := newBloger("Tom")
	ff := friendlyFans{fans{base{
		id:   1,
		name: "眼泪cry",
	}}}
	ff1 := unfriendlyFans{fans{base{
		id:   2,
		name: "天蓝色的水",
	}}}
	bloger.attachBloger(&ff)
	bloger.attachBloger(&ff1)
	bloger.releaseBlog("今天天气不错", "心情")
	bloger.releaseBlog("今晚吃川菜", "美食")
	bloger.browseComment(2)
	//bloger.detachBloger(&ff)

}
